委托
什么是委托(Delegate)
委托的意思很直观,比方说A委托B做一件什么什么事。
实现一个委托
首先定义一个委托,使用delegate
关键字,它的语法是:1
public delegate void TestEventHandler();
在这里必须要注意的是命名时最好在后面加上EventHandler
,这是一种大家约定俗成标准的写法,并且都不要问为什么。(ps:随便什么命名都是没问题的,但是为了程序可读性尽量这样写吧。)
声明一个委托TestEventHandler(要委托的方法)
,例如声明上面的委托:1
TestEventHandler testDelegate = new TestEventHandler(方法);
可以理解为将一个具体的方法添加到这个委托。
然后再调用这个委托就行了,调用方式和普通的方法调用一样:1
testDelegate();
举个实例来说明一下,假如说A和B是室友,A的快递到了,让B帮忙取一下,使用委托来实现这个例子。完整代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24class RoomMateA{
public delegate void AEventHandler(); //定义一个委托
public void DelegateMate(){
Console.WriteLine("我不想动,我让朋友帮我处理事情!");
//声明委托,委托的参数是被委托执行的方法
AEventHandler myDelegate = new AEventHandler(RoomMateB.PickupDelivery);
myDelegate(); //委托已经被添加了方法,直接执行即可
}
}
class RoomMateB{
public static void PickupDelivery(){ //添加到委托的方法,要领快递的是悲剧的室友
Console.WriteLine("我很无奈,我替死肥宅朋友去取快递!");
}
}
class Program{
static void Main(){
RoomMateA A = new RoomMateA();
RoomMateB B = new RoomMateB();
A.DelegateMate();
}
}
委托链
委托链也很容易理解,就是将多个要委托的方法添加到委托上。方法的调用顺序就是方法被添加到委托上的顺序。
接着上边的例子,假如B要帮A去取快递了,正要出门,A“委托”B下楼的时候顺便把垃圾倒了呗。。。
我们不考虑B的感受,只来看实现方式。
其实很简单,只需要在上面定义过的委托上增加一个B去倒垃圾的方法就行了:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28class RoomMateA{
public delegate void AEventHandler(); //定义一个委托
public void DelegateMate(){
Console.WriteLine("我不想动,我让朋友帮我处理事情!");
//声明委托,委托的参数是被委托执行的方法
AEventHandler myDelegate = new AEventHandler(RoomMateB.PickupDelivery);
myDelegate += RoomMateB.TakeOutRubbish; //将扔垃圾方法添加到委托
myDelegate(); //调用委托
}
}
class RoomMateB{
public static void PickupDelivery(){
Console.WriteLine("我很无奈,我替死肥宅朋友去取快递!");
}
public static void TakeOutRubbish(){ //添加到委托的新方法,替室友扔垃圾
Console.WriteLine("我要哭了,我还要替他扔垃圾!");
}
}
class Program{
static void Main(){
RoomMateA A = new RoomMateA();
RoomMateB B = new RoomMateB();
A.DelegateMate();
}
}
事件(Event)
什么是事件
事件可以是一些操作,比如鼠标点击,或者一些情况出现,比如说上面例子快递到了这个情况的发生,或者是应用程序中出现的某一状态,比如说断开数据库。
实现一个事件
事件是一种特殊的委托,它使用的是发布-订阅模型,。在模型中存在着发布者和订阅者,当出现一个事件时,发布者将事件通知到订阅者,订阅者就可以调用注册好的方法。发布者包含了事件委托定义,订阅者包含了事件处理程序,也就是需要注册的方法。
首先还是定义一个委托1
public delegate void TestEventHandler();
然后定义一个基于上面委托类型的事件1
public delegate void TestEventHandler TestEvent;
假如要在EventTest()
方法里面触发(和方法调用一样)1
2
3public void EventTest(){
TestEvent();
}
添加订阅者要执行的方法1
TestEvent += TestEventHandler(订阅者要执行的方法)
还以上面的例子,快递员电话告知室友A快递到了,然后A获得事件消息并委托B去取快递:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36class DeliveryMan //新增一个快递员类
{
public delegate void DeliveryEventHandler(); //定义委托
public event DeliveryEventHandler deliveryEvent; //定义基于委托的事件
public void Delivery() //送快递事件
{
Console.WriteLine("下楼取快递了!");
if (deliveryEvent != null) //检查订阅者是否为空,看看有没有人要等着接快递
deliveryEvent(); //触发送快递事件
}
}
class RoomMateA
{
...
}
class RoomMateB
{
...
}
class Program
{
static void Main()
{
DeliveryMan deliveryMan = new DeliveryMan(); //实例化
RoomMateA A = new RoomMateA(); //实例化
RoomMateB B = new RoomMateB(); //实例化
deliveryMan.deliveryEvent += new DeliveryMan.DeliveryEventHandler(A.DelegateMate); //添加订阅者
deliveryMan.Delivery(); //执行送快递方法
}
}
委托和事件的异同
从上面的例子很容易看出来,事件和委托是非常相似的,都是将方法作为参数,事实上前面提过的事件是一种特殊的委托。事件只能通过某些方法激发调用,要调用某个事件必须调用这些方法,而委托是可以直接使用代码调用的,可能他们的底层实现机制都是一样的,但我还没有过多研究。